#ifndef xpack_utils_lexx
#define xpack_utils_lexx
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::utils_lexx::inc
#include"define/base_type.hpp"
#include"macro/xexport.hpp"
#include"meta/unsigned_type.hpp"
#include"meta/is_signed.hpp"
#pragma pop_macro("xuser")

namespace mixc::utils_lexx::origin{
    template<class type_t, uxx bytes_v = sizeof(type_t)>
    requires(0 < bytes_v and bytes_v <= sizeof(u64))
    struct lexx{
    private:
        u08 items[bytes_v];
    public:
        lexx() : items{} {}
        lexx(type_t value) : 
            items{} {
            for(uxx i = 0; i < bytes_v; i++){
                auto get_byte       = u08(inc::unsigned_type<type_t>(value) >> (i * xbitsof(u08)));
                items[i] = get_byte;
            }
        }

        operator type_t() const {
            type_t result = inc::is_signed<type_t> and (items[bytes_v - 1] & 0x80) ? type_t(inc::unsigned_type<type_t>(-1) << (bytes_v * xbitsof(u08))) : type_t{};

            for(uxx i = 0; i < bytes_v; i++){
                result |= type_t(items[i]) << (i * xbitsof(u08));
            }
            return result;
        }
    };

    using leu16         = lexx<uxx, 2>;
    using lei16         = lexx<ixx, 2>;
    using leu24         = lexx<uxx, 3>;
    using lei24         = lexx<ixx, 3>;
    using leu32         = lexx<uxx, 4>;
    using lei32         = lexx<ixx, 4>;
    using leu40         = lexx<u64, 5>;
    using lei40         = lexx<i64, 5>;
    using leu48         = lexx<u64, 6>;
    using lei48         = lexx<i64, 6>;
    using leu56         = lexx<u64, 7>;
    using lei56         = lexx<i64, 7>;
    using leu64         = lexx<u64, 8>;
    using lei64         = lexx<i64, 8>;
}

#endif

xexport_space(mixc::utils_lexx::origin)
